/** 
 * 题目: 实现一个type类型，用于约束特殊时间格式的字符串例子:
 * FormatDate<"DD-MM-YY">
 * 允许的字符串为:const date: FormatDate<"DD-MM-YY"> = "12-12-2024" "12-02-2024"
 * 不允许的字符串为:const date: FormatDate<"DD-MM-YY"> = "112-12-2024" "12-112-2024" "12-12-12024"
 * 时间格式支持多种分符: -、.、/
 * */
type Seperator = '-' | '.' | '/';
type NonZero = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type FirstD = 0 | 1 | 2 | 3
type FirstM = 0 | 1
type NonNegative = 0 | NonZero;

type FormatDate1 = `${number}${Seperator}${number}${Seperator}${number}`
const fd1: FormatDate1 = `22-2-2`
// type FormatDate = <DD extends NonZero,OP extends Seperator,MM extends NonZero,YYYY extends NonZero>
type TDD = `${FirstD}${NonNegative}`
type TMM = `${FirstM}${NonNegative}`
type TYY = `${NonZero}${NonNegative}${NonNegative}${NonNegative}`
type FormatDate2 = `${TDD}${Seperator}${TMM}${Seperator}${TYY}`;
const fd2: FormatDate2 = `18-01-2024`

type CamelCaseAll1<Str extends string> =
  Str extends `${infer Left}_${infer Right}${infer Rest}` ?
  `${Left}${GetUppercase<Right>}${CamelCase<Rest>}` : Str;
type ReplaceAll1<Str extends string,From extends string,To extends string> =
  Str extends `${infer Prefix}${From}${infer Subfix}` ?
  `${Prefix}${To}${ReplaceAll1<Subfix,From,To>}`
  : Str;
type FormatDate3<template extends string> =
  template extends `${infer DD}${Seperator}${infer MM}${Seperator}${infer YYYY}` ?
  `${TDD}${Seperator}${TMM}${Seperator}${number}` : ''
const fd: FormatDate3<'DD-MM-YYYY'> = '20-12-2020'


type Num = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;

type Num2 = Num | 0

type YYYY = `19${Num2}${Num2}` | `20${Num2}${Num2}`;
type YY = `${Num2}${Num2}` | `${Num2}${Num2}`;

type MM = `0${Num}` | `1${0 | 1 | 2}`;

type DD = `${0}${Num}` | `${1 | 2}${Num2}` | `3${0 | 1}`;
type IsEqual1<A,B> = (A extends B ? true : false) & (B extends A ? true : false);
type GenStr<Type extends string> =
  Type extends 'YYYY' ?
  YYYY :
  (Type extends 'YY' ?
    YY :
    (Type extends 'MM' ?
      MM :
      DD));
// _是类型变量，用于其他未定义的字符串
type FormatDate<Pattern extends string> =
  Pattern extends `${infer Aaa}${Seperator}${infer Bbb}${Seperator}${infer Ccc}` ?
  (Pattern extends `${Aaa}${infer Sep}${Bbb}${infer _}${Ccc}` ?
    (IsEqual1<Sep,_> extends true ?
      `${GenStr<Aaa>}${Sep}${GenStr<Bbb>}${Sep}${GenStr<Ccc>}` :
      never) :
    never) :
  never;

const formatDateA: FormatDate<'YYYY-MM-DD'> = '2023-01-02';

const formatDateB: FormatDate<'DD-MM-YY'> = '01-02-24';

// const formatDateC: FormatDate<'DD/MM/YY'> = '2024-01-02';


type Flatten<T> = T extends any[] ? T[number] : T;
// Extracts out the element type.
type Str = Flatten<string[]>;